/**
 * @p.md
 * 
 * PingPong 示例，演示 Actor 系统的基本使用
 */
import { Actor } from '../actor';
import { Context } from '../context';
import { ActorSystem } from '../actorSystem';
import { Props } from '../props';
import { PID } from '../pid';

/**
 * Ping 消息
 */
interface PingMessage {
  type: 'ping';
  count: number;
}

/**
 * Pong 消息
 */
interface PongMessage {
  type: 'pong';
  count: number;
}

/**
 * Ping Actor 实现
 */
class PingActor implements Actor {
  private pongActor?: PID;
  
  /**
   * 接收并处理消息
   * @param context 当前 Actor 上下文
   */
  receive(context: Context): void {
    const message = context.message();
    
    // 处理启动消息
    if (message === 'start' && !this.pongActor) {
      console.log('[PingActor] Starting ping-pong sequence');
      
      // 创建 Pong Actor
      this.pongActor = context.spawn(Props.fromProducer(() => new PongActor()));
      
      // 发送第一个 ping 消息
      const pingMessage: PingMessage = { type: 'ping', count: 0 };
      context.send(this.pongActor, pingMessage);
    }
    // 处理 pong 消息
    else if (typeof message === 'object' && message && message.type === 'pong') {
      const pongMessage = message as PongMessage;
      console.log(`[PingActor] Received pong: ${pongMessage.count}`);
      
      // 如果计数小于 10，继续 ping-pong
      if (pongMessage.count < 10) {
        const pingMessage: PingMessage = { type: 'ping', count: pongMessage.count + 1 };
        
        // 延迟 500ms 发送下一个 ping，使输出更容易观察
        setTimeout(() => {
          if (this.pongActor) {
            context.send(this.pongActor, pingMessage);
          }
        }, 500);
      } else {
        console.log('[PingActor] Ping-pong completed');
        
        // 停止 pong actor
        if (this.pongActor) {
          context.stop(this.pongActor);
          this.pongActor = undefined;
        }
      }
    }
  }
}

/**
 * Pong Actor 实现
 */
class PongActor implements Actor {
  /**
   * 接收并处理消息
   * @param context 当前 Actor 上下文
   */
  receive(context: Context): void {
    const message = context.message();
    
    // 处理 ping 消息
    if (typeof message === 'object' && message && message.type === 'ping') {
      const pingMessage = message as PingMessage;
      console.log(`[PongActor] Received ping: ${pingMessage.count}`);
      
      // 回复 pong 消息
      const pongMessage: PongMessage = { type: 'pong', count: pingMessage.count };
      context.respond(pongMessage);
    }
  }
}

/**
 * 运行 PingPong 示例
 */
export function runPingPongExample(): void {
  console.log('Starting PingPong example...');
  
  // 创建 Actor 系统
  const system = new ActorSystem();
  
  // 创建 Ping Actor
  const pingActorPid = system.root.spawn(Props.fromProducer(() => new PingActor()));
  
  // 启动 ping-pong 序列
  system.root.send(pingActorPid, 'start');
  
  // 等待 ping-pong 完成后关闭系统
  setTimeout(async () => {
    console.log('Shutting down Actor system...');
    await system.terminate();
    console.log('Actor system terminated');
  }, 10000);
} 